package com.Register.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.Register.dto.ESDTO;
import com.Register.entity.WxUser;
import com.Register.es.ActivityDoc;
import com.Register.mapper.WxUserMapper;
import com.Register.service.WxUserService;
import com.Register.vo.ActivityResponseVO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class WxUserServiceImpl extends ServiceImpl<WxUserMapper, WxUser> implements WxUserService{

    @Resource
    private RestHighLevelClient restHighLevelClient;

    @Override
    public ActivityResponseVO queryAllActivity() throws IOException {
        //1.创建Request
        SearchRequest request=new SearchRequest("activities");
        //2.组织请求参数
        request.source().query(QueryBuilders.matchAllQuery());
        //3.发送请求
        SearchResponse response=restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //4.解析响应
        return handleResponse(response);
    }

    @Override
    public ActivityResponseVO queryMatchActivity(ESDTO esdto) throws IOException {
        //1.创建Request
        SearchRequest request=new SearchRequest("activities");
        //2.1组织请求参数
        request.source().query(QueryBuilders.matchQuery("activityName",esdto.getContext()));
        //2.2排序参数
        request.source().sort("beginTime", SortOrder.DESC);
        //2.3分页参数
        request.source().from((esdto.getPageNo()-1)*esdto.getPageSize()).size(esdto.getPageSize());
        //3.发送请求
        SearchResponse response=restHighLevelClient.search(request,RequestOptions.DEFAULT);
        //4.解析响应
        return handleResponse(response);
    }

    @Override
    public ActivityResponseVO queryMathActivityWithHighlight(ESDTO esdto) throws IOException {
        //1.创建Request
        SearchRequest request=new SearchRequest("activities");
        //2.1组织请求参数
        request.source().query(QueryBuilders.matchQuery("activityName",esdto.getContext()));
        //2.2排序参数
        request.source().sort("beginTime", SortOrder.DESC);
        //2.3分页参数
        request.source().from((esdto.getPageNo()-1)*esdto.getPageSize()).size(esdto.getPageSize());
        //2.4高亮条件
        request.source().highlighter(
                SearchSourceBuilder.highlight()
                        .field("activityName")
                        .preTags("<span style='color: red;'>") // 使用单引号
                        .postTags("</span>")
        );
        //3.发送请求
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //解析响应
        return handleHighlightResponse(search);
    }

    /*
    解析得到的结果
     */
    private static ActivityResponseVO handleResponse(SearchResponse response){
        SearchHits hits = response.getHits();
        ActivityResponseVO activityResponseVO = new ActivityResponseVO();
        //1.获取总条数
        activityResponseVO.setTotal(hits.getTotalHits().value);
        //2.遍历结果数组
        List<ActivityDoc> docList=new ArrayList<>();
        SearchHit[] searchHits = hits.getHits();
        for(SearchHit hit:searchHits){
            //得到_source,原始json文档
            String source=hit.getSourceAsString();
            //反序列化,然后加入数组中
            ActivityDoc doc= JSONUtil.toBean(source,ActivityDoc.class);
            docList.add(doc);
        }
        activityResponseVO.setResponseVO(docList);
        return activityResponseVO;
    }

    /*
    高亮解析结果
     */
    private static ActivityResponseVO handleHighlightResponse(SearchResponse response){
        SearchHits hits = response.getHits();
        ActivityResponseVO activityResponseVO = new ActivityResponseVO();
        //1.获取总条数
        activityResponseVO.setTotal(hits.getTotalHits().value);
        //2.遍历结果数组
        List<ActivityDoc> docList=new ArrayList<>();
        SearchHit[] searchHits = hits.getHits();
        for(SearchHit hit:searchHits){
            //得到_source,原始json文档
            String source=hit.getSourceAsString();
            //反序列化,然后加入数组中
            ActivityDoc doc= JSONUtil.toBean(source,ActivityDoc.class);
            //获取高亮结果
            Map<String, HighlightField> hfs=hit.getHighlightFields();
            if(CollUtil.isNotEmpty(hfs)){
                //有高亮结果，获取activityName的高亮结果
                HighlightField hf=hfs.get("activityName");
                if(hf!=null){
                    //获取第一个高亮结果片段
                    String hfName = hf.getFragments()[0].string();
                    doc.setActivityName(hfName);
                }
            }
            docList.add(doc);
        }
        activityResponseVO.setResponseVO(docList);
        return activityResponseVO;
    }
}
